package exam;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.TreeSet;
import java.util.stream.Collectors;

/**
 * 1.性能比较
 * 经过测试，Scanner的平均耗时是BufferedReader的10倍左右，在网上刷OJ的时候如果没有特殊困难，强烈推荐使用BufferedReader读取数据！
 *
 * @author shenenlu 2021年04月29日 下午15:32:29
 */
public class Main {


    public static void main(String[] args) {
        /**
         * HJ2
         * 计算字符个数
         */
//        HJ2();
        /**
         * HJ3
         * 	明明的随机数
         */
//        HJ3();
        /**
         * HJ4
         * 	字符串分隔
         * 	while循环处理字符串
         * 	Arrays.fill初始化字符串
         */
//        HJ4();
        /**
         * HJ5
         * 	进制转换
         */
//        HJ5();
        /**
         * HJ13
         * 句子逆序
         */
//        HJ13();
        /**
         * 	HJ39
         * 	判断两个IP是否属于同一子网
         * 	split点号要转义
         *  二进制移位操作
         *  二进制和字符串转换
         */
//        HJ39();
        /**
         * 	HJ97
         * 	记负均正
         */
//        HJ97();
        /**
         * HJ30
         * 字符串合并处理
         * Integer.valueOf用法
         */
//        HJ30();

        /**
         * HJ107
         * 求解立方根
         */
//        HJ107();

    }

    /**
     * HJ107
     * 求解立方根
     */
    public static void HJ107() throws IOException {
        BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in));
        String str;
        while ( (str = bufferedReader.readLine()) != null){
            boolean isNegative = false;
            if( str.startsWith("-") ){
                str = str.replace("-", "");
                isNegative = true;
            }

            final int scale = 14;
            BigDecimal result = new BigDecimal("0.0").setScale(scale, RoundingMode.HALF_UP);
            BigDecimal step = new BigDecimal("1.0").setScale(scale, RoundingMode.HALF_UP);;
            final BigDecimal resultCompare = new BigDecimal("0.0001");
            final BigDecimal zero = new BigDecimal("0");
            final BigDecimal stepDivide = new BigDecimal("10");
            final BigDecimal bigDecimal = new BigDecimal(str).setScale(scale,RoundingMode.HALF_UP);

            while ( true ){
                final BigDecimal addStepTemp = result.add(step);
                final BigDecimal computeTemp = addStepTemp.multiply(addStepTemp).multiply(addStepTemp).setScale(scale, RoundingMode.HALF_UP);
                if( computeTemp.subtract(bigDecimal)
                        .compareTo(zero) > 0 ){
                    step = step.divide(stepDivide ,scale,RoundingMode.HALF_UP );
                    continue;
                }
                result = result.add(step);
                if( bigDecimal.subtract(computeTemp)
                        .compareTo( resultCompare ) < 0){
                    break;
                }
            }
            if( isNegative){
                result = result.multiply(new BigDecimal("-1"));
            }
//            System.out.println(result.setScale(4, RoundingMode.HALF_UP));
            System.out.println(result.setScale(1, RoundingMode.HALF_UP));
        }
    }

    /**
     * 	计算字符个数
     */
    public static void HJ2() throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        String str;
        while ( (str=bufferedReader.readLine()) != null){
            str = str.toLowerCase();
            char chr = bufferedReader.readLine().toLowerCase().toCharArray()[0];
            int count = 0;
            for( int i =0; i<  str.length(); i++){
                if( str.charAt(i) == chr ){
                    count ++;
                }
            }
            System.out.print(count);
        }
    }

    /**
     * 	HJ3
     * 	明明的随机数
     */
    public static void HJ3(){
        Scanner sc = new Scanner(System.in);
        List<Integer> numberList = new ArrayList<>();
        while (sc.hasNextLine()){
            String str = sc.nextLine();
            if( str == null || "".equals(str.trim())){
                break;
            }
            numberList.add(Integer.valueOf(str));
        }
        if( numberList.size() == 0 ){
            return;
        }
        List<Integer> result = new ArrayList<>();
        int nextCountIndex = 0;
        do{
            final int count = numberList.get(nextCountIndex);
            TreeSet<Integer> treeSet = new TreeSet<>();
            for( int i = nextCountIndex + 1; i < nextCountIndex + count + 1; i++){
                treeSet.add(numberList.get(i));
            }
            nextCountIndex += count + 1;
            result.addAll(treeSet);
        }while (nextCountIndex < numberList.size());

        result.forEach(System.out::println);
        sc.close();
    }



    /**
     * 	字符串分隔
     * 	while循环处理字符串
     * 	Arrays.fill初始化字符串
     */
    public static void HJ4(){
        final int STR_LENGTH_LIMIT = 8;
        Scanner sc = new Scanner(System.in);
        List<String> result = new ArrayList<>();
        while (sc.hasNextLine()){
            final String str = sc.nextLine();
            if( str == null || "".equals(str.trim())){
                break;
            }
            final int strLength =  str.length();
            final int mod = strLength % STR_LENGTH_LIMIT;
            final int fillZeroCount = (mod == 0)  ? 0: STR_LENGTH_LIMIT - mod ;
            final char[] zeroCharArray = new char[fillZeroCount];
            Arrays.fill(zeroCharArray, '0');

            int needToProcessLength = strLength;
            int currentStartIndex = 0;
            while ( needToProcessLength > STR_LENGTH_LIMIT ){
                result.add(str.substring( currentStartIndex, currentStartIndex + STR_LENGTH_LIMIT));
                needToProcessLength -= STR_LENGTH_LIMIT;
                currentStartIndex += STR_LENGTH_LIMIT;
            }
            if( needToProcessLength > 0 ){
                result.add(str.substring(currentStartIndex).concat(String.valueOf(zeroCharArray)));
            }
        }
        result.forEach(System.out::println);
        sc.close();
    }



    /**
     * 	进制转换
     */
    public static void HJ5(){
        Scanner sc = new Scanner(System.in);
        List<Integer> result = new ArrayList<>();
        while (sc.hasNextLine()){
            final String str = sc.nextLine();
            if( str == null || "".equals(str.trim())){
                break;
            }
            result.add(Integer.valueOf(str.replace("0x",""), 16));
        }
        if( result.size() == 0 ){
            return;
        }
        result.forEach(System.out::println);
        sc.close();
    }


    /**
     * 	句子逆序
     */
    public static void HJ13(){
        Scanner sc = new Scanner(System.in);
        final String str = sc.nextLine();
        if( str == null || "".equals(str.trim())){
            return;
        }
        String[] s = str.split(" ");

        for(int i=s.length-1; i >= 0; i--){
            System.out.print(s[i] + " ");
        }
        sc.close();
    }


    /**
     * 	HJ39
     * 	判断两个IP是否属于同一子网
     * 	split点号要转义
     *  二进制移位操作
     *  二进制和字符串转换
     */
    public static void HJ39(){
        Scanner sc = new Scanner(System.in);
        List<String> strList = new ArrayList<>();
        while (sc.hasNextLine()){
            final String str = sc.nextLine();
            if( str == null || "".equals(str.trim())){
                break;
            }
            strList.add(str);
        }
        if( strList.size() == 0 ){
            return;
        }
        List<Integer> result = new ArrayList<>();

        int ipMaskIndex = 0;
        while ( ipMaskIndex + 2 < strList.size()  ){
            try {
                final String ipMaskStr = strList.get(ipMaskIndex);
                final String ip1Str = strList.get(ipMaskIndex + 1);
                final String ip2Str = strList.get(ipMaskIndex + 2);

                int ipMask = strToIpInt(ipMaskStr, true);
                int ip1 = strToIpInt(ip1Str, false);
                int ip2 = strToIpInt(ip2Str, false);

                if( (ipMask & ip1) == (ipMask & ip2) ){
                    result.add(0);
                }else{
                    result.add(2);
                }
            }catch (Exception e){
                result.add(1);
            }
            ipMaskIndex += 3;
        }
        result.forEach(System.out::println);
        sc.close();
    }


    /**
     * split点号要转义
     * 二进制移位操作
     * 二进制和字符串转换
     *
     * @param ip
     * @return
     */
    private static int strToIpInt(String ip, boolean isIpMask){
        String[] split = ip.split("\\.");
        if( split.length != 4 ){
            throw new IllegalArgumentException();
        }
        int i1 = Integer.parseInt(split[0]);
        int i2 = Integer.parseInt(split[1]);
        int i3 = Integer.parseInt(split[2]);
        int i4 = Integer.parseInt(split[3]);
        if( i1 < 0 || i1 > 255 ){
            throw new IllegalArgumentException();
        }
        if( i2 < 0 || i2 > 255){
            throw new IllegalArgumentException();
        }
        if( i3 < 0 || i3 > 255){
            throw new IllegalArgumentException();
        }
        if( i4 < 0 || i4 > 255){
            throw new IllegalArgumentException();
        }
//        return (i1 << 24) + (i2 << 16) + (i3 << 8) + (i4);
        int ipIntValue = (i1 << 24) | (i2 << 16) | (i3 << 8) | (i4);

        if( isIpMask ){
            String s = Integer.toBinaryString(ipIntValue);
            if( s.length() < 32 && s.startsWith("1")){
                throw new IllegalArgumentException();
            }
            if( s.contains("01")){
                throw new IllegalArgumentException();
            }
        }
        return ipIntValue;
    }



    /**
     * 	HJ97
     * 	记负均正
     */
    public static void HJ97(){
        Scanner sc = new Scanner(System.in);
        List<String> strList = new ArrayList<>();
        while (sc.hasNextLine()){
            final String str = sc.nextLine();
            if( str == null || "".equals(str.trim())){
                break;
            }
            strList.add(str);
        }
        if( strList.size() == 0 ){
            return;
        }
        List<String> result = new ArrayList<>();

        int countIndex = 0;
        while ( countIndex + 1 < strList.size()  ){
            try {
                final int count = Integer.parseInt(strList.get(countIndex));
                final List<Integer> numberList = Arrays.stream(strList.get(countIndex + 1)
                        .split(" ")).map(Integer::parseInt).collect(
                        Collectors.toList());
                int negativeCount = 0;
                int positiveCount = 0;
                int sum = 0;
                String avgResult = "0.0";
                for( int i : numberList){
                    if( i < 0){
                        negativeCount++;
                    }else{
                        positiveCount++;
                        sum += i;
                    }
                }
                if( positiveCount != 0){
                    BigDecimal sumDecimal = new BigDecimal(sum + ".0000");
                    BigDecimal positiveCountDecimal = new BigDecimal(positiveCount + ".0000");
                    avgResult = sumDecimal.divide(positiveCountDecimal, BigDecimal.ROUND_HALF_UP)
                            .setScale(1,BigDecimal.ROUND_HALF_UP).toPlainString();
                }

                result.add(negativeCount + " " + avgResult);
            }catch (Exception e){
//                e.printStackTrace();
                throw new IllegalArgumentException();
            }
            countIndex += 2;
        }
        result.forEach(System.out::println);
        sc.close();
    }



    /**
     * 	HJ30
     * 	字符串合并处理
     *
     */
    public static void HJ30(){
        Scanner sc = new Scanner(System.in);
        List<String> strList = new ArrayList<>();
        while (sc.hasNextLine()){
            final String str = sc.nextLine();
            if( str == null || "".equals(str.trim())){
                break;
            }
            strList.add(str);
        }
        if( strList.size() == 0 ){
            return;
        }
        List<String> result = new ArrayList<>();

        for( String str :strList ){
            try {
                String[] splitStrArray = str.split(" ");
                if( splitStrArray.length != 2 ){
                    throw new IllegalArgumentException();
                }
                char[] concatCharArr = splitStrArray[0].concat(splitStrArray[1]).toCharArray();
                char[] oddCharArr = new char[concatCharArr.length % 2==0? concatCharArr.length/2 : concatCharArr.length/2+1];
                char[] evenCharArr = new char[concatCharArr.length / 2];
                for( int i=0; i< concatCharArr.length; i++){
                    if( i % 2 == 0){
                        evenCharArr[i / 2] = concatCharArr[i];
                    }else{
                        oddCharArr[ (i-1) / 2] = concatCharArr[i];
                    }
                }
                Arrays.sort(oddCharArr);
                Arrays.sort(evenCharArr);
                for( int i=0; i < concatCharArr.length; i++){
                    if( i % 2 == 0){
                        concatCharArr[i] = processChar(evenCharArr[i / 2]);
                    }else{
                        concatCharArr[i] = processChar(oddCharArr[ (i-1) / 2]);
                    }
                }
                result.add(new String(concatCharArr).toUpperCase());
            }catch ( IllegalArgumentException e ){
                result.add("illegal input: " + str);
            }
        }
        result.forEach(System.out::println);
        sc.close();
    }

    private static char processChar(char c) {
        try {
            int integer = Integer.valueOf(c + "", 16);
            char[] binaryCharArr = Integer.toBinaryString(integer).toCharArray();
            for( int i=0; i < binaryCharArr.length / 2 ; i++){
                char temp = binaryCharArr[i];
                binaryCharArr[i] = binaryCharArr[binaryCharArr.length - 1 - i];
                binaryCharArr[binaryCharArr.length - 1 - i] = temp;
            }
            return Integer.toHexString(Integer.valueOf(new String(binaryCharArr), 2))
                    .toCharArray()[0];
        }catch (NumberFormatException e){
            return c;
        }
    }


}
